package edu.spbsu.nonsm00th.computgeom.chull.impl;

import edu.spbsu.nonsm00th.computgeom.chull.ConvexHull;
import edu.spbsu.nonsm00th.computgeom.util.D2Util;
import edu.spbsu.nonsm00th.computgeom.util.D3Util;
import edu.spbsu.nonsm00th.computgeom.util.DNUtil;
import edu.spbsu.nonsm00th.model.Line;
import edu.spbsu.nonsm00th.model.Plane3D;
import edu.spbsu.nonsm00th.model.Point;
import edu.spbsu.nonsm00th.util.Precondition;
import java.util.ArrayList;
import java.util.List;

/**
 * Realization of simple convex hull algorithm.
 * Should be used only for 3-dimensional point lists.
 *
 * @author mbuzdov
 */
public class D3SimpleConvexHull implements ConvexHull {

    public void convexHull(List<Point> list) {
        Precondition.argsNotNull(list);
        if (0 == list.size()) {
            return;
        }

        /* Find the cartesian minimum point min */
        Point min = DNUtil.findCartesianMinimum(list);

        /* Find point d1point, which is farest to the min */
        double maxd1 = 0.0;
        Point d1point = null;
        for (Point next : list) {
            double d = DNUtil.getDistance(min, next);
            if (d > maxd1) {
                d1point = next;
                maxd1 = d;
            }
        }
        if (null == d1point) {
            list = new ArrayList<Point>();
            list.add(min);
            return;
        }

        /* Find point d2point, which is farest to the (min; d1point) line. */
        Line l = new Line(min, d1point);
        double maxd2 = 0.0;
        Point d2point = null;
        for (Point next : list) {
            double d = l.getDistance(next);
            if (d > maxd2) {
                d2point = next;
                maxd2 = d;
            }
        }
        if (null == d2point) {
            list = new ArrayList<Point>();
            list.add(min);
            list.add(d1point);
            return;
        }

        /* Find point d3, which is farest to the (min, d1point, d2point) plane */
        Plane3D p3d = new Plane3D(l, d2point);
        double maxd3 = 0.0;
        Point d3point = null;
        for (Point next : list) {
            double d = p3d.getDistance(next);
            if (d > maxd3) {
                d3point = next;
                maxd3 = d;
            }
        }
        if (null == d3point) {
            //TODO: find chull for bad situation
            return;
        }
        //TODO: continue here to find non trivial situation
    }

    private List<Integer> findInners() {
        return null;
    }

    private void convexHull2(List<Point> list) {
        Precondition.argsNotNull(list);
        if (0 == list.size()) {
            return;
        }
    }
}
